package com.gcsoftware.web.controller;

import com.gcsoftware.configs.MailConfigs;
import com.gcsoftware.web.beans.request.GetAccountRegisterReq;
import com.gcsoftware.web.beans.T_COM_SYS_USER;
import com.gcsoftware.web.beans.T_GW_COMPANY;
import com.gcsoftware.web.service.T_COM_SYS_LOGSERVICE;
import com.gcsoftware.authentications.beans.UserInfo;
import com.gcsoftware.authentications.helper.ShiroUtils;
import com.gcsoftware.web.service.T_COM_SYS_USER_SERVICE;
import com.gcsoftware.web.service.T_GW_COMPANY_SERVICE;
import com.gcsoftware.utils.log.LogUtils;
import com.gcsoftware.utils.MapUtils;
import com.gcsoftware.utils.SysConst;
import com.gcsoftware.web.service.T_GW_VERIFY_SERVICE;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by qs on 2018/3/19.
 */
@Controller
public class UserLoginController {

    @Autowired
    private T_COM_SYS_LOGSERVICE logService;

    @Autowired
    private T_COM_SYS_USER_SERVICE userService;

    @Autowired
    private T_GW_COMPANY_SERVICE companyService;


    @Autowired
    private T_GW_VERIFY_SERVICE verifyService;

    @Autowired
    private MailConfigs mailConfigs;

    @RequestMapping(value = "/login" , method = RequestMethod.GET)
    public String toLogin() {
        return "login";
    }

    @RequestMapping(value = "/login" , method = RequestMethod.POST)
    @ResponseBody
    public MapUtils doLogin(@RequestParam(value = "loginName")String loginName,
                            @RequestParam(value = "loginPwd") String loginPwd,
                            @RequestParam(value = "ifRemember" , required = false) String ifRemember) {

        T_COM_SYS_USER userInfo = userService.get(null,loginName,null);
        String userId = null != userInfo ? userInfo.getC_USER_ID() : "0";
            try{
                Subject subject = SecurityUtils.getSubject();
                UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPwd);
                token.setRememberMe("1".equals(ifRemember) ? true : false);
                subject.login(token);
                Map<String , Object> map = new HashMap<>();
                //这边定义登录成功后跳转的页面，根据实际情况修改

                UserInfo user = (UserInfo) subject.getSession().getAttribute("user");
                if(null != user) {
                    if ("ADMIN".equals(user.getUserRole())) {
                        map.put("page" , "/");
                    } else {
                        map.put("page" , "/enroll/apps");
                    }
                }
                String logId = logService.insertSysLog(LogUtils.LOG_TYPE_LOGIN,"登录成功", SysConst.DICT_OPERATE_STATUS_SUCCESS);
                if (StringUtils.isNotBlank(logId)) {
                    user.setLoginId(logId);
                    subject.getSession().setAttribute("user",user);
                }
                return MapUtils.ok(map);
            }catch (UnknownAccountException e) {
                logService.insertSysLog(LogUtils.LOG_TYPE_LOGIN,"没有权限或账号不存在", SysConst.DICT_OPERATE_STATUS_FAILED,userId,null);
                return MapUtils.error("账号不存在或没有权限登录");
            }catch (IncorrectCredentialsException e) {
                logService.insertSysLog(LogUtils.LOG_TYPE_LOGIN,"账号或密码不正确", SysConst.DICT_OPERATE_STATUS_FAILED,userId,null);
                return MapUtils.error("账号或密码不正确");
            }catch (LockedAccountException e) {
                logService.insertSysLog(LogUtils.LOG_TYPE_LOGIN,"账号已被锁定", SysConst.DICT_OPERATE_STATUS_FAILED,userId,null);
                return MapUtils.error("账号已被锁定,请联系管理员");
            }catch (AuthenticationException e) {
                logService.insertSysLog(LogUtils.LOG_TYPE_LOGIN,"账户验证失败", SysConst.DICT_OPERATE_STATUS_FAILED,userId,null);
                return MapUtils.error("账户验证失败");
            }
        /*}*/
    }

    /**
     * 退出
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout() {
        ShiroUtils.logout();
        return toLogin();
    }

    @RequestMapping("/register")
    public String register() {
        return "register";
    }

    @ResponseBody
    @Transactional
    @RequestMapping(value = "/register" , method = RequestMethod.POST)
    public MapUtils registers(GetAccountRegisterReq req) {
        Map<String , Object> map = new HashMap<>();
        if (null != req) {
            T_GW_COMPANY com = companyService.get(null,req.getC_COMPANY_NAME());
            if (null == com) {
                com = new T_GW_COMPANY();
                com.setC_COMPANY_NAME(req.getC_COMPANY_NAME());
                com.setC_COMPANY_REMARK(req.getC_COMPANY_REMARK());
                com.setC_LINK_EMAIL(req.getC_USER_EMAIL());
                com.setC_LINK_MAN(req.getC_LINK_MAN());
                com.setC_LINK_TEL(req.getC_LINK_TEL());
                com.setC_COMPANY_STATUS(SysConst.DICT_COMPANY_STATUS_REGISTER);
                Map companyMap = new HashMap();
                companyMap.putAll(companyService.insert(com));
                if (0 != (Integer) companyMap.get("code")) {
                    return MapUtils.error((String) companyMap.get("msg"));
                }
            } else {
                map.put("companyExists","已存在同名公司，直接在公司下创建登录账号！");
            }

            T_COM_SYS_USER user = userService.get(null,req.getC_LOGIN_NAME(),null);
            if(null == user) {
                user = userService.get(null,null,req.getC_USER_EMAIL());
                if (null != user) {
                    return MapUtils.error("已存在邮箱相同的账户！");
                }
                user = new T_COM_SYS_USER();
                user.setC_ROLE_ID(SysConst.DFT_ROLE_COMPANY);
                user.setC_COMPANY_ID(com.getC_COMPANY_ID());
                user.setC_STATUS(SysConst.DICT_USER_STATUS_REGISTER);
                user.setC_LOGIN_NAME(req.getC_LOGIN_NAME());
                user.setC_USER_EMAIL(req.getC_USER_EMAIL());
                if (0 == (Integer) userService.insert(user).get("code")) {
                    if (0 == (Integer) userService.insertUserPwd(user.getC_USER_ID(), req.getC_USER_PWD()).get("code")) {
                        //注册厂家 并发送注册邮件
                        verifyService.insertVerify(user.getC_USER_ID(),SysConst.VERIFY_TYPE_COMPANY_REGISTER,null,null,null,com.getC_COMPANY_NAME());
                        //注册账户 并发送注册审核邮件
                        verifyService.insertVerify(user.getC_USER_ID(),SysConst.VERIFY_TYPE_USER_REGISTER,null,null,null,user.getC_LOGIN_NAME());
                    } else {
                        //如果密码保存失败，则删除用户
                        userService.delete(user.getC_USER_ID());
                        return MapUtils.error("注册账号失败");
                    }
                }
                return MapUtils.ok(map);
            } else {
                return MapUtils.error("已存在同名账号！");
            }
        }
        return MapUtils.error("未读取到注册信息！") ;
    }

    @RequestMapping(value = "reset-pwd")
    public String resetPwd() {
        return "password";
    }

    @RequestMapping("/setPwd/{tid}")
    public String setPwd(@PathVariable(value = "tid") String tid) {

        return "password";
    }

    @ResponseBody
    @RequestMapping(value = "/saveNewPassword" , method = RequestMethod.POST)
    public MapUtils saveNewPassword(@RequestParam(value = "c_OLD_PWD")String c_OLD_PWD,
                                    @RequestParam(value = "c_NEW_PWD") String c_NEW_PWD) {
        UserInfo userInfo = ShiroUtils.getSessionAttribute("user");
        /*pwd.setC_SALT(RandomStringUtils.randomAlphanumeric(20));
        pwd.setC_PWD_PLAINTEXT(pwd.getC_PASSWORD());
        pwd.setC_PASSWORD(ShiroUtils.sha256(pwd.getC_PASSWORD(), pwd.getC_SALT()));
*/
        if (ShiroUtils.sha256(c_OLD_PWD , userInfo.getSalt()) .equals(userInfo.getUserPwd())) {
            return userService.insertUserPwd(userInfo.getUserId(),c_NEW_PWD);
        } else {
            return MapUtils.error("原密码输入错误！");
        }
    }
}
